package controllers

import (
	. "chess_platform/internal/common"
	"chess_platform/internal/validation"
	"encoding/json"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/logs"
)

//这是最基本的controller，分别给pc,h5,client三个平台继承

type BaseController struct {
	beego.Controller
	Res   *Response
	Valid validation.Validation
}

type Token struct {
	Token    string `json:"token"`
	DeviceId string `json:"device_id"` //设备ID用于识别用户是否在其它地方登录
}

type Response struct {
	Code  int64       `json:"code"`
	Msg   string      `json:"msg,omitempty"`
	Count interface{} `json:"count,omitempty"` //分页统计个数
	Token string      `json:"token,omitempty"`
	Data  interface{} `json:"data,omitempty"`
}

func (b *BaseController) IsDevelopMode() bool {
	if beego.BConfig.RunMode == "pro" {
		b.Res.Code = ErrRunningMode
		b.Res.Msg = MsgErrRunningMode
		b.Response()
		return false
	}
	return true
}

func (b *BaseController) IsServerStop() bool {
	if PlatformConf.Status != ServerNormal && PlatformConf.Status != 0 {
		b.Res.Code = ErrServerStop
		b.Res.Msg = "服务器维护中....."
		b.Response()
		return false
	}
	return true
}

func (b *BaseController) VerifyParamsError() bool {
	if b.Valid.HasErrors() {
		b.Res.Code = ErrVerifyParams
		for _, err := range b.Valid.Errors {
			if beego.BConfig.RunMode == "dev" {
				b.Res.Msg = err.Key + " " + err.Message
			} else {
				b.Res.Msg = err.Message
			}
			b.Response()
			return false
		}
	}
	return true
}

func (b *BaseController) ValidParams(p interface{}, l ...*logs.BeeLogger) bool {
	_, err := b.Valid.RecursiveValid(p)
	if err != nil {
		if len(l) == 1 {
			l[0].Error(fmt.Sprintf("校验参数错误:%v", err.Error()))
		}
		b.SystemError(err.Error())
		return false
	}
	return b.VerifyParamsError()
}

func (b *BaseController) SystemError(msg ...string) string {
	b.Res.Code = ErrSystem
	if beego.BConfig.RunMode == "dev" {
		b.Res.Msg = MsgErrSystem
		for _, v := range msg {
			b.Res.Msg = b.Res.Msg + "," + v
		}
	} else {
		b.Res.Msg = MsgErrSystem
	}
	b.Response()
	returnMsg := MsgErrSystem
	for _, v := range msg {
		returnMsg = returnMsg + "," + v
	}
	return returnMsg
}

func (b *BaseController) DatabaseError(msg ...string) string {
	if len(msg) > 0 {
		if msg[0] == ErrInvalidConn.Error() || msg[0] == ErrBadConnNoWrite.Error() {
			b.Res.Code = ErrDatabaseRetry
			b.Res.Msg = MsgDatabaseBusy
			b.Response()
		} else {
			b.Res.Code = ErrDatabase
			b.Res.Msg = MsgErrDatabase
			b.Response()
		}
		returnMsg := MsgErrDatabase
		for _, v := range msg {
			returnMsg = returnMsg + "," + v
		}
		return returnMsg
	}
	b.Res.Code = ErrDatabase
	if beego.BConfig.RunMode == "dev" {
		b.Res.Msg = MsgErrDatabase
		for _, v := range msg {
			b.Res.Msg = b.Res.Msg + "," + v
		}
	} else {
		b.Res.Msg = MsgErrDatabase
	}
	b.Response()
	returnMsg := MsgErrDatabase
	for _, v := range msg {
		returnMsg = returnMsg + "," + v
	}
	return returnMsg
}

func (b *BaseController) LoginRetry(msg ...string) string {
	b.Res.Code = ErrRetry
	if beego.BConfig.RunMode == "dev" {
		b.Res.Msg = MsgErrLoginRetry
		for _, v := range msg {
			b.Res.Msg = b.Res.Msg + "," + v
		}
	} else {
		b.Res.Msg = MsgErrLoginRetry
	}
	b.Response()
	returnMsg := MsgErrLoginRetry
	for _, v := range msg {
		returnMsg = returnMsg + "," + v
	}
	return returnMsg
}

func (b *BaseController) Retry(msg ...string) string {
	b.Res.Code = ErrRetry
	for _, v := range msg {
		b.Res.Msg = b.Res.Msg + "," + v
	}
	b.Response()
	return b.Res.Msg
}

func (b *BaseController) ResponseSuccess(msg ...string) {
	b.Res.Code = Success
	if len(msg) == 1 {
		b.Res.Msg = msg[0]
	} else {
		b.Res.Msg = MsgSuccess
	}
	b.Response()
}

func (b *BaseController) ResponseSuccessTwo(msg ...string) {
	b.Res.Code = SuccessTwo
	if len(msg) == 1 {
		b.Res.Msg = msg[0]
	} else {
		b.Res.Msg = MsgSuccess
	}
	b.Response()
}

func (b *BaseController) ResponseFail(msg ...string) {
	b.Res.Code = Fail
	if len(msg) == 1 {
		b.Res.Msg = msg[0]
	} else {
		b.Res.Msg = MsgFail
	}
	b.Response()
}
func (b *BaseController) DecodeParamsError(err error) {
	b.Res.Code = ErrDecodeParams
	if beego.BConfig.RunMode == "dev" {
		b.Res.Msg = MsgErrDecodeParams + err.Error()
	} else {
		b.Res.Msg = MsgErrDecodeParams
	}
	b.Response()
}

func (b *BaseController) Unmarshal(v interface{}) error {
	return json.Unmarshal(b.Ctx.Input.RequestBody, &v)
}

func (b *BaseController) DecodeParams(v interface{}, l ...*logs.BeeLogger) bool {
	err := b.Unmarshal(v)
	if err != nil {
		if len(l) == 1 {
			l[0].Error(fmt.Sprintf("%v:%v", MsgErrDecodeParams, err.Error()))
		}
		b.DecodeParamsError(err)
		return false
	}
	return true
}

func (b *BaseController) Response() {
	b.Data["json"] = b.Res
	b.ServeJSON()
}

func (b *BaseController) ResponseRawByte(data []byte) {
	b.Ctx.ResponseWriter.Write(data)
}
func (b *BaseController) ResponseRawString(data string) {
	b.Ctx.ResponseWriter.Write([]byte(data))
}
